﻿#ifndef BUFFER_OBJECT_H_
#define BUFFER_OBJECT_H_

#include <memory>
#include "render_system/basic_define.h"
#include "render_system/gl_render_system_define.h"

class BufferObject
{
public:
    enum Type {
        ARRAY = 0,
        ATOMIC_COUNTER,
        COPY_READ, 
        COPY_WRITE, 
        DRAW_INDIRECT,
        ELEMENT_ARRAY,
        PIXEL_PACK,
        PIXEL_UNPACK,
        TEXTURE,
        TRANSFORM_FEEDBACK,
        UNIFORM
    };

    enum Usage {
        STREAM_DRAW = 0,
        STREAM_READ,
        STREAM_COPY,
        STATIC_DRAW,
        STATIC_READ,
        STATIC_COPY,
        DYNAMIC_DRAW,
        DYNAMIC_READ,
        DYNAMIC_COPY
    };

    GL_RENDER_SYSTEM_API BufferObject();

    GL_RENDER_SYSTEM_API ~BufferObject();

    GL_RENDER_SYSTEM_API void bind();

    GL_RENDER_SYSTEM_API void unBind();

    GL_RENDER_SYSTEM_API void read(
        const size_t uSizeInBytes,
        const PixelFormat& pixelformat,
        const Type type,
        const Usage usage,
        const void* pData);

    // properties
    GL_RENDER_SYSTEM_API size_t ID() const;

    GL_RENDER_SYSTEM_API PixelFormat pixelFormat() const;

    GL_RENDER_SYSTEM_API size_t glFormat() const;

    GL_RENDER_SYSTEM_API size_t glConponentType() const;

    GL_RENDER_SYSTEM_API size_t channels() const;

    GL_RENDER_SYSTEM_API size_t numberOfData() const;

private:
    void _copy2gpu();

private:
    unsigned int          _uID;
    Type                  _type;
    Usage                 _usage;
    PixelFormat           _pixelFormat;
    size_t                _uSizeInBytes;
    std::shared_ptr<char> _pData;
};

typedef std::shared_ptr<BufferObject> BufferObjectPtr;

#endif